iT邦幫忙

2022 iThome 鐵人賽

DAY 23
0
Mobile Development

關於 Flutter 開發的一些設計雜談系列 第 23

Day 23 - 暫存一些資料,增加使用者體驗

  • 分享至 

  • xImage
  •  

當我們在開發應用程式的時候,常常會遇到一種需要 Cache 資料的情境:當使用者打開畫面,我們從 API 或 DB 讀取資料,讓資料成功顯示在畫面上。過了一段時間,使用再次打開相同畫面時,我們希望不要再次呼叫 API,直接顯示上一次取得的資料,以節省流量。為了完成這個功能,我們從會在原本的程式碼中,加上一段 Cache 資料的實作。

it_img_22_1.png
https://dartpad.dev/?id=4f6412479033c28f75da665ca1ed433d

這個做法雖然可以滿足我們的需求,但是也帶來了一個問題。這段類別違反了單一職責,他同時具備了 Cache 的職責與讀取資料的職責。假設今天我們不想把資料暫存在記憶體中,而是想暫存在 sqlite 中,我們就會需要回頭修改這個類別。其次,雖然 NewsRepository 的設計本身符合開放封閉原則,但是我們修改時卻不是拓展而是修改,反而讓設計不符合原則了。

裝飾者模式 (Decorator Pattern)

為了尋求更好的設計,我們可以使用裝飾者模式。我們建立一個 NewsCachedDecorator,讓它實作與 NewsRepository 相同的介面,並把 NewsRepostory 傳入裝飾者中。

it_img_22_2.png
https://dartpad.dev/?id=faa4503480e41c56bbf62248da73c225

最後再依賴注入的時候,CachedDecorator 包在實作外面,當畫面呼叫 NewsRepository 時,自然會先經過 Cache,由 Cache 決定是否重打 API。

it_img_22_3.png

當變化來臨時

假設今天我們不需要 Cache 了,我們可以直接移除 Cache 裝飾者就好。

it_img_22_4.png

或者,我們想更換 Cache 的實作方式,改成使用套件而非自己實作時,也可以修改 Cache 裝飾者就好,而不用修改原本的 NewsRepository 實作。

it_img_22_5.png

應該在哪邊 Cache 呢?

在上面的例子中,我們把 Cache 設計在 Repository 層,但是其實我們也可以把 Cache 的職責,往上放到狀態管理層,往下放到實際呼叫 Web API 的地方。許多套件本身也都有提供 Cache 的功能,讓開發者可以更簡單的 Cache API 的回傳值。那到底我們應該放在哪邊才對呢?其實這個問題並沒有正確答案,需要讀者根據自己的情境選擇。當我們很確定所有 API 都有相同的 Cache 行為時,那把 Cache 職責放在呼叫 Web API 的地方可能會適合。但是當今天我們需要根據不同資料,而有不同的 Cache 行為時,放在 Repository 可能比較合適。

結論

Cache 是一種很常見的使用場景,透過裝飾者模式分離 Cache 與呼叫 API 的職責,讓程式符合單一職責與開放封閉原則。當時決定要使用 Cache 時,也需要決定要把 Cache 實作在什麼地方,這其中就需要讀者根據需求與專案的狀況選擇。


上一篇
Day 22 - 使用依賴注入套件
下一篇
Day 24 - 利用 Interceptor 處理 Token
系列文
關於 Flutter 開發的一些設計雜談30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言